<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模拟axios拦截器</title>
</head>
<body>
    <script>
        function Axios(config){
            this.config=config;
            this.interceptors={
                request: new InterceptorManager(),
                response: new InterceptorManager(),
            }
        }
        function InterceptorManager(){
            this.handlers=[];
        }

        //为InterceptorManager原型上添加use方法
        InterceptorManager.prototype.use=function(fulfilled,rejected){
            this.handlers.push({  // 方法实际是将传入的参数添加到handlers数组中
                fulfilled,
                rejected
            })
        }


        //发送请求
        function dispatchRequest(config){
            return new Promise((resolve,reject)=>{
                resolve({
                    status:200,
                    statueText:'OK'
                })
            })
        }
        // 向Axios的原型中添加request方法
        Axios.prototype.request=function(config){
            let promise= Promise.resolve(config);  // 创建一个promise对象
            const chains= [dispatchRequest,undefined];
            this.interceptors.request.handlers.forEach(item=>{
                chains.unshift(item.fulfilled,item.rejected)  //在chains头部添加内容
            })
            this.interceptors.response.handlers.forEach(item=>{
                chains.push(item.fulfilled,item.rejected)  //在 chains发问添加内容
            })
            while(chains.length>0){
               promise = promise.then(chains.shift(),chains.shift()); //调用里面的方法
            }
            return promise;
        }


        let context= new Axios({});
        let axios= Axios.prototype.request.bind(context)
        Object.keys(context).forEach(key=>{
            axios[key]=context[key];
        })

        // 设置请求拦截器  config 配置对象
        axios.interceptors.request.use(function one(config) {
            console.log('请求拦截器 成功 - 1号');
            return config;
        }, function one(error) {
            console.log('请求拦截器 失败 - 1号');
            return Promise.reject(error);
        });

        axios.interceptors.request.use(function two(config) {
            console.log('请求拦截器 成功 - 2号');
            return config;
        }, function two(error) {
            console.log('请求拦截器 失败 - 2号');
            return Promise.reject(error);
        });

        // 设置响应拦截器
        axios.interceptors.response.use(function (response) {
            console.log('响应拦截器 成功 1号');
            return response;
        }, function (error) {
            console.log('响应拦截器 失败 1号')
            return Promise.reject(error);
        });

        axios.interceptors.response.use(function (response) {
            console.log('响应拦截器 成功 2号')
            return response;
        }, function (error) {
            console.log('响应拦截器 失败 2号')
            return Promise.reject(error);
        });

        //发送请求
        axios({
            method: 'GET',
            url: 'http://localhost:3000/posts'
        }).then(response => {
            console.log(response);
        });

    </script>
</body>
</html> 